﻿using System;
using System.Text;
using UnityEngine;
using System.Diagnostics;
using System.Collections.Generic;
using UnityEngine.Profiling;
using UnityEngine.SceneManagement;

public class XLogger
{
    static private long lastLogTime;

    public const int LEVEL_ALL = -1;
    public const int LEVEL_TEMP = 0;
    public const int LEVEL_TEST = 1;
    public const int LEVEL_LOG = 2;

    public const int LEVEL_WARN = 8;

    public const int LEVEL_SERVER = 9;
    public const int LEVEL_ERROR = 10;

    static public void SetLogLevel(int lv)
    {
        LogLevel = lv;
    }
#if UNITY_EDITOR || UNITY_STANDALONE_WIN
    static private int LogLevel = LEVEL_ALL;
#elif RO_DEBUG || DEVELOPMENT_BUILD
    static private int LogLevel = LEVEL_ALL;
#else
    static private int LogLevel = LEVEL_ERROR;
#endif

#if RO_DEBUG || UNITY_EDITOR || DEVELOPMENT_BUILD
    static public bool IsRoDebug = true;
#else
    static public bool IsRoDebug = false;
#endif

    static public bool mSendLogToServer = false;

    private static void LogWithColor(string message, Color color,int level)
    {
        if (level < LogLevel)
        {
            mTraceBack = null;
            return;
        }

        StringBuilder sb = new StringBuilder();
        long nowTime = DateTime.Now.Ticks / 10000;//ms

#if UNITY_EDITOR
        int colorInt = ((int)(color.r * 255f) << 16) | ((int)(color.g * 255f) << 8) | (int)(color.b * 255f);
        long offsetTime = lastLogTime > 0 ? nowTime - lastLogTime : 0;

        sb.Append("<color=#")
            .Append(colorInt.ToString("X6"))
            .Append(">")
            .Append("[")
            .Append(offsetTime)
            .Append("]")
            .Append("-->")
            .Append(message)
            .Append("</color>");
#else
            sb.Append(message);
#endif
        if (mTraceBack != null)
        {
            sb.Append(mTraceBack);
            mTraceBack = null;
        }
        lastLogTime = nowTime;
        UnityEngine.Debug.Log(sb.ToString());
    }
    //public 
    [Conditional("DEVELOPMENT_BUILD")]
    [Conditional("UNITY_EDITOR")]
    public static void Log(string message, int layer = 1)
    {
        LogWithColor(message, Color.green, LEVEL_LOG);
        //AddLog(message);
    }

    public static void LogError(string message)
    {
        if (LEVEL_ERROR < LogLevel)
        {
            mTraceBack = null;
            return;
        }
        long nowTime = DateTime.Now.Ticks / 10000;//ms
        long offsetTime = lastLogTime > 0 ? nowTime - lastLogTime : 0;
        lastLogTime = nowTime;
        if (mTraceBack != null)
        {
            UnityEngine.Debug.LogError("[" + offsetTime + "] Error:" + message + "\r\n" + mTraceBack);
            mTraceBack = null;
        }
        else
        {
            UnityEngine.Debug.LogError("[" + offsetTime + "] Error:" + message);
        }
    }
    [Conditional("UNITY_EDITOR")]
    public static void LogEditorError(string message)
    {
        LogError(message);
    }

    public static void LogErrorFormat(string format, params object[] args)
    {
        if (LEVEL_ERROR < LogLevel)
        {
            mTraceBack = null;
            return;
        }
        string errorLog = string.Format(format, args);
        LogError(errorLog);
    }
    [Conditional("DEVELOPMENT_BUILD")]
    [Conditional("UNITY_EDITOR")]
    public static void LogWarn(string message, int layer = 1)
    {
        LogWithColor(message, Color.yellow, LEVEL_WARN);
    }

    [Conditional("UNITY_EDITOR")]
    public static void LogTest(string message, int layer = 1)
    {
        LogWithColor(message, Color.magenta, LEVEL_TEST);
    }

    [Conditional("UNITY_EDITOR")]
    public static void LogTemp(string message, int layer = 1)
    {
        Color color = new Color(0.4f,0.6f,1);
        LogWithColor(message, color, LEVEL_TEMP);
    }

    [Conditional("LOG_MASSIVE")]
    public static void LogMassive(string message, int layer = 1)
    {
        LogWithColor(message, Color.white, LEVEL_TEST);
    }

    public static void LogToServer(string message)
    {
        LogWithColor(message, Color.red, XLogger.LEVEL_SERVER);
    }

    static private string mTraceBack;
    public static void SetTraceBack(string traceback)
    {
        mTraceBack = traceback;
    }


    static private Queue<string> m_logQueue = new Queue<string>();
    static private int m_LogIndex = 0;
    static private string m_ClientId;
    static private string m_DeviceModel;
    static private string m_ScreenSize;
    static private string m_SendingLog;
    public static void RecordErrorLog()
    {
        if (Application.isEditor) return;
        m_ClientId = PlayerPrefs.GetString("deviceUniqueIdentifier", string.Empty);
        if (string.IsNullOrEmpty(m_ClientId))
        {
            m_ClientId = SystemInfo.deviceUniqueIdentifier;
            PlayerPrefs.SetString("deviceUniqueIdentifier", m_ClientId);
        }

        m_DeviceModel = SystemInfo.deviceModel;
        m_ScreenSize = Screen.width + "x" + Screen.height;
        Application.logMessageReceived += OnLog;
        mSendLogToServer = true;
    }

    private static void OnLog(string condition, string stackTrace, LogType type)
    {
        if (type == LogType.Error
            || type == LogType.Exception
            || type == LogType.Assert)
        {
            string content = condition + "\n" + stackTrace + ".";
			Dream.PlatformManager.GetInstance ().SDKLogException (type.ToString (), condition, stackTrace);
            //
        }
    }

    private static Dictionary<string, string> m_LogMap = new Dictionary<string, string>(16);
    private static float m_LastLogToServerTime = 0f;

    public static float GetLastLogToServerTime()
    {
        return m_LastLogToServerTime;
    }

    static private Dictionary<string, string> m_CachedVersion = new Dictionary<string, string>(5);
    static private string GetVersionStr(string versionStr)
    {
        if (string.IsNullOrEmpty(versionStr))
        {
            return string.Empty;
        }

        if (m_CachedVersion.ContainsKey(versionStr))
        {
            return m_CachedVersion[versionStr];
        }
        string newVersionStr = versionStr.Replace('.', '_');
        m_CachedVersion.Add(versionStr, newVersionStr);
        return newVersionStr;
    }

    private static void trySendLog()
    {
        if (m_SendingLog != null) return;

        if (m_logQueue.Count>0)
        {
            m_SendingLog = m_logQueue.Dequeue();

            WWWForm post = new WWWForm();
            post.AddField("log", m_SendingLog);
			Dream.PlatformManager.GetInstance().SendLogToSDK (LogType.Error, m_SendingLog);
        }
    }

    private static void OnSendComplete(string result)
    {
        m_SendingLog = null;
        trySendLog();
    }



}